﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace com.ReinforceLab.AudioModem.LinkLayer
{
    /// <summary>
    /// 調歩同期式の、バイトデータを再生
    ///     LSb-first
    ///     オーバサンプリング 4
    ///     スタートビット、ストップビットそれぞれ1ビットの'0'
    ///     
    /// キャリア断絶による、1ブロックのデータ伝送と判断。ここで初めて読み出しができる。    
    /// 遷移条件：
    ///     NoCarrier →OutOfSync
    ///         符号なし整数でスライスレベル以上なら＋1、以下なら－1(0クリップ)。レベルが4以上で遷移。
    /// </summary>            
    /*class AsyncByteReader
    {
        
        #region Variables
        enum RecoveryState { START_BIT, DATA_BITS, STOP_BIT };
        
        readonly List<Byte> _rcvBuf;

        RecoveryState _state;
        byte _recoveryData;
        int _recoveryBitPos;
        int _indexOffset;        
        #endregion

        #region Properties        
        public bool HasReceived { get { return _rcvBuf.Count > 0; } }            
        #endregion

        #region Construcotr
        public AsyncByteReader()
        {
            _rcvBuf = new List<byte>();
            _state = RecoveryState.START_BIT;
            _indexOffset = 0;
        }
        #endregion

        #region Private methods
        int startBit(int[] waveform, int index)
        {            
            for (; index < waveform.Length; index++)
            {
                // wide pulse
                if(waveform[index] == 2)
                {                        
                    System.Diagnostics.Debug.WriteLine("StartBit -> DataBits");                        
                    _recoveryData = 0;                        
                    _recoveryBitPos = 0;                                            
                    _state = RecoveryState.DATA_BITS;                        
                    return (index +1);
                }
            }
            return index;
        }      
        int dataBits(int[] waveform, int index)
        {
            for (; index < waveform.Length; index ++)
            {
                // no carrier                        
                if (waveform[index] == 0)
                {
                    System.Diagnostics.Debug.WriteLine("DataBits -> CarrierDet");
                    _state = RecoveryState.START_BIT;
                    return index;
                }

                _recoveryBitPos++;
                _recoveryData >>= 1;

                if (waveform[index] == 1)
                    _recoveryData |= 0x80;                                   

                if (_recoveryBitPos > 7)
                {
                    System.Diagnostics.Debug.WriteLine("DataBits -> StopBits");
                    _recoveryBitPos = 0;                    
                    _state = RecoveryState.STOP_BIT;
                    return (index + 1);
                }

            }
            return index;
        }
        int stopBit(int[] waveform, int index)
        {
            // is narrow pulse?
            if (waveform[index] == 1)
            {
                System.Diagnostics.Debug.WriteLine(String.Format("Receiving: 0x{0:X}.", _recoveryData));
                _rcvBuf.Add(_recoveryData);
            }
            else
            {
                System.Diagnostics.Debug.WriteLine(String.Format("Illegal stop bit: 0x{0:X}. (stop bit : {1}", _recoveryData, waveform[index]));
            }
            _state = RecoveryState.START_BIT;
            return (index + 1);
        }
        #endregion

        #region Public methods
        /// <summary>
        /// データをリカバリします。これを読み出したあとは、HasReceivedが有効ならば、データバッファを読み出してください。次に呼び出したとき、このバッファは破壊されています。
        /// </summary>
        /// <param name="waveform"></param>
        public void Recovery(int[] waveform)
        {
            int index = _indexOffset;
            while (index < waveform.Length)
            {
                switch (_state)
                {
                    case RecoveryState.START_BIT:
                        index = startBit(waveform, index);
                        break;
                    case RecoveryState.DATA_BITS:
                        index = dataBits(waveform, index);
                        break;
                    case RecoveryState.STOP_BIT:
                        index = stopBit(waveform, index);
                        break;
                    default: _state = RecoveryState.START_BIT;
                        return;
                }
            }
            _indexOffset = index - waveform.Length;
        }
        /// <summary>
        /// バッファのブロックデータを読みだします
        /// </summary>        
        public Byte[] Read()
        {
            var buf = _rcvBuf.ToArray();
            _rcvBuf.Clear();
            return buf;
        }
        #endregion
    }
    */
}
